﻿using NetworkCommsDotNet;
using NetworkCommsDotNet.Connections;
using NetworkCommsDotNet.Connections.TCP;
using NetWorkTcpLibrary;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using System.Windows.Forms;

namespace WinFrom_TcpClient
{
    public partial class Client_Form : Form
    {
        /// <summary>
        /// 连接状态
        /// </summary>
        private bool ClientOnlineBool = false;

        /// <summary>
        /// 多开线程状态控制
        /// </summary>
        private bool ThreadStatus = true;

        /// <summary>
        /// 连接列表
        /// </summary>
        private List<NetWorkTcpClient> netWorkTcpClients = new List<NetWorkTcpClient>();

        public Client_Form()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 双击清空接收的消息框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void richTextBox_Messge_DoubleClick(object sender, EventArgs e)
        {
            richTextBox_Messge.Clear();
        }

        /// <summary>
        /// 连接按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_Startlisten_Click(object sender, EventArgs e)
        {
            try
            {
                if (ClientOnlineBool)
                {
                    //停止连接
                    foreach (NetWorkTcpClient item in netWorkTcpClients)
                    {
                        item.StopClient();
                    }
                    //为了保险清理一下
                    NetworkComms.ClearDic();
                    netWorkTcpClients.Clear();
                    ClientOnlineBool = !ClientOnlineBool;
                    button_Start.Text = "开始连接";
                    listBox_ConnList.Items.Clear();
                    button_Start.BackColor = Color.Red;
                }
                else
                {
                    for (int i = 0; i < Convert.ToInt32(textBox_ThreadNum.Text); i++)
                    {
                        Action action = new Action(() =>
                        {
                            NetWorkTcpClient netWorkTcpClient = new NetWorkTcpClient(textBox_Address.Text, "ServerTest", "ReturnStrng");//多来测试我们关掉自动重连，不然线程太多容易崩溃
                            //NetWorkTcpClient.IsRepetitionStatus = false;
                            netWorkTcpClient.ReConnectNumEvent += NetWorkTcpClient_ReConnectNumEvent;//重连次数事件
                            netWorkTcpClient.EventStateChangesEvent += NetWorkTcpClient_EventStateChangesEvent;//连接状态改变事件
                            netWorkTcpClient.EventMessageHandle += NetWorkTcpClient_RevciveEvent;
                            netWorkTcpClient.EventReturnMessageHandle += Receive_RevciveEvent;
                            netWorkTcpClients.Add(netWorkTcpClient);
                        });
                        action.BeginInvoke(null, null);//新线程异步创建
                    }

                    ClientOnlineBool = !ClientOnlineBool;
                    button_Start.Text = "已启动连接";
                    button_Start.BackColor = Color.Green;
                }
            }
            catch (Exception ex)
            {
                richTextBox_Messge.AppendText($"\n{ex.Message}");
            }
        }

        private void NetWorkTcpClient_EventStateChangesEvent(ConnectionInfo connectionInfo, bool obj)
        {
            Invoke(new Action(() =>
            {
                if (obj)
                {
                    //客户端上线添加到列表显示
                    var ip = connectionInfo.LocalEndPoint.ToString();
                    if (listBox_ConnList.Items.IndexOf(ip) == -1)
                    {
                        listBox_ConnList.Items.Add(ip);
                    }
                }
                else
                {
                    listBox_ConnList.Items.Remove(connectionInfo.LocalEndPoint.ToString());
                }
            }));
        }

        /// <summary>
        /// 重连次数事件
        /// </summary>
        /// <param name="obj"></param>
        private void NetWorkTcpClient_ReConnectNumEvent(ConnectionInfo connectionInfo, int obj)
        {
            Invoke(new Action(() =>
            {
                if (obj != 0)
                {
                    if (connectionInfo.LocalEndPoint.ToString() != "0.0.0.0:0")
                    {
                        richTextBox_Messge.AppendText($"\n{connectionInfo.LocalEndPoint}第{obj}次重连");
                    }
                    else
                    {
                        richTextBox_Messge.AppendText($"\n客户端正在尝试第{obj}次创建连接");
                    }
                }
                else
                {
                    richTextBox_Messge.AppendText($"\n{connectionInfo.LocalEndPoint}连接成功");
                }
            }));
        }

        /// <summary>
        /// 接收消息处理事件
        /// </summary>
        /// <param name="obj"></param>
        private void NetWorkTcpClient_RevciveEvent(Connection connection, XYZ obj)
        {
            Invoke(new Action(() =>
            {
                richTextBox_Messge.AppendText($"\n收到服务端{connection.ConnectionInfo.RemoteEndPoint.ToString()}消息-->x:{obj._X},y:{obj._Y},z:{obj._Z}");
            }));
        }

        /// <summary>
        /// 接收回执消息处理事件
        /// </summary>
        /// <param name="obj"></param>
        private void Receive_RevciveEvent(Connection connection, string obj)
        {
            Invoke(new Action(() =>
            {
                richTextBox_Messge.AppendText($"\n服务端回执消息-->{obj}");
            }));
        }

        /// <summary>
        /// 发送消息（字符串）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_SendMessge_Click(object sender, EventArgs e)
        {
            //遍历给所有连接发消息
            foreach (NetWorkTcpClient _netWorkTcpClient in netWorkTcpClients)
            {
                _netWorkTcpClient.SendObj<string>("ReceiveStrName", richTextBox_SendMessge.Text);
            }
        }

        /// <summary>
        /// 发送消息（字符串带返回）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_ReturnSendMessge_Click(object sender, EventArgs e)
        {
            //遍历给所有连接发消息
            foreach (NetWorkTcpClient _netWorkTcpClient in netWorkTcpClients)
            {
                _netWorkTcpClient.SendReturnObj<string, string>("ReturnStrName", "ReturnStrng", richTextBox_SendMessge.Text, 1000);
            }
        }

        /// <summary>
        /// 发送对象
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_SenObject_Click(object sender, EventArgs e)
        {
            Random rd = new Random();
            //遍历给所有连接发消息
            foreach (NetWorkTcpClient _netWorkTcpClient in netWorkTcpClients)
            {
                XYZ xYZ = new XYZ();
                xYZ._X = rd.Next(0, 1000);
                xYZ._Y = rd.Next(0, 1000);
                xYZ._Z = rd.Next(0, 1000);
                _netWorkTcpClient.SendObj<XYZ>("ReceiveObjName", xYZ);
            }
        }

        /// <summary>
        /// 发送对象（带返回）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_ReturnSendObject_Click(object sender, EventArgs e)
        {
            Random rd = new Random();
            //遍历给所有连接发消息
            foreach (NetWorkTcpClient _netWorkTcpClient in netWorkTcpClients)
            {
                XYZ xYZ = new XYZ();
                xYZ._X = rd.Next(0, 1000);
                xYZ._Y = rd.Next(0, 1000);
                xYZ._Z = rd.Next(0, 1000);
                _netWorkTcpClient.SendReturnObj<XYZ, string>("ReturnObjName", "ReturnStrng", xYZ,1000);
            }
        }

        private void textBox_ThreadNum_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar != 8 && !Char.IsDigit(e.KeyChar))
            {
                e.Handled = true;
            }
        }

        private void textBox_ThreadNum_TextChanged(object sender, EventArgs e)
        {
            if (textBox_ThreadNum.Text == "")
                textBox_ThreadNum.Text = 0.ToString();
            int number = int.Parse(textBox_ThreadNum.Text);
            textBox_ThreadNum.Text = number.ToString();
            if (number > 500)
            {
                textBox_ThreadNum.Text = 500.ToString();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            IPEndPoint RemotePoint = new IPEndPoint(IPAddress.Parse("192.168.0.16"), 1234);//服务器ip地址
            IPEndPoint LocalPoint = new IPEndPoint(IPAddress.Parse("192.168.0.16"), 5678);//本地ip地址
            ConnectionInfo connnectionInfo = new ConnectionInfo(RemotePoint, LocalPoint);
            TCPConnection.GetConnection(connnectionInfo);
        }
    }
}